<template>
  <div class="calendar-box"
       ref="calendar">
    <el-collapse-transition>
      <div class="el-picker-panel el-date-picker el-popper"
           x-placement="bottom-start"
           v-show="showCalendarBox==true">
        <div class="el-picker-panel__body-wrapper">
          <div class="el-picker-panel__body">
            <div class="el-date-picker__header">
              <button type="button"
                      aria-label="上俩个月"
                      class="el-picker-panel__icon-btn el-date-picker__prev-btn el-icon-arrow-left"
                      :class="changePrevCls(aYearData[0].aMonthData[3][3].yy,aYearData[0].aMonthData[3][3].mm)"
                      @click="prevTwoMonthDate(aYearData[0].aMonthData[3][3].yy,aYearData[1].aMonthData[3][3].yy,aYearData[0].aMonthData[3][3].mm)"></button>
              <button type="button"
                      aria-label="下俩个月"
                      class="el-picker-panel__icon-btn el-date-picker__next-btn el-icon-arrow-right"
                      @click="nextTwoMonthDate(aYearData[1].aMonthData[3][3].yy,aYearData[0].aMonthData[3][3].yy,aYearData[0].aMonthData[3][3].mm)"></button>
            </div>
            <div class="el-picker-panel__content"
                 v-for="(item,index) in aYearData"
                 :key="index">
              <p class="cp-tit">
                <span role="button"
                      class="el-date-picker__header-label">{{item.title}}</span>
              </p>
              <table cellspacing="0"
                     cellpadding="0"
                     class="el-date-table">
                <tbody>
                  <tr>
                    <!---->
                    <th>日</th>
                    <th>一</th>
                    <th>二</th>
                    <th>三</th>
                    <th>四</th>
                    <th>五</th>
                    <th>六</th>
                  </tr>
                  <tr class="el-date-table__row"
                      v-for="(dateItem,dateIdx) in item.aMonthData"
                      :key="dateIdx">
                    <td class="available"
                        :ref="dayItem.yy+'-'+dayItem.mm+'-'+dayItem.content"
                        :class="setDayClass(dayItem.yy+'-'+dayItem.mm+'-'+dayItem.content)"
                        v-for="(dayItem,dayIdx) in dateItem"
                        :key="dayIdx"
                        @click="clkdayBoxFn(dayItem,dayIdx,index,item.title,dayItem.content)">
                      <div>
                        <span>{{dayItem.content}}</span>
                      </div>
                    </td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
        </div>

        <!-- 小三角 -->
        <div x-arrow=""
             class="popper__arrow"
             style="left: 300px;"></div>
      </div>
    </el-collapse-transition>
  </div>
</template>

<script>
export default {
  props: {
    // 是否展示日历框
    showCalendarBox: { type: Boolean, default: false },
  },
  data() {
    return {
      // 过去日期标签
      everTag: false,
      activeCls: ' current',
      everCls: ' disabled',
      todayCls: ' today',
      // 向前翻按钮禁用样式
      notPrev: ' disabled',
      weeks: [
        { id: 0, name: '日', fullName: '周日' },
        { id: 1, name: '一', fullName: '周一' },
        { id: 2, name: '二', fullName: '周二' },
        { id: 3, name: '三', fullName: '周三' },
        { id: 4, name: '四', fullName: '周四' },
        { id: 5, name: '五', fullName: '周五' },
        { id: 6, name: '六', fullName: '周六' },
      ],
      month: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
      // 排序后的月份
      orderMonth: [],
      // 排序后的年份
      aYear: [],
      aYearData: [],
      // 当前年月日
      nowYY: '',
      nowMM: '',
      nowDD: '',
      // 选中的日期
      selDate: '',
    };
  },
  created() {
    // 获取当前年月日
    this.nowYY = new Date().getFullYear();
    this.nowMM = new Date().getMonth();
    this.nowDD = new Date().getDate();
    this.get_twoMonth_Data(this.nowYY, this.nowMM, 'created');
  },
  mounted() {
  },
  methods: {
    // 获取一年每月份的天数
    getDayCount($yy, $mm) {
      const daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
      if (($yy % 4 === 0 && $yy % 100 !== 0) || $yy % 400 === 0) {
        daysInMonth[1] = 29;
      }
      return daysInMonth[$mm];
    },
    // 获取某一天是星期几
    getWeekByDay(dayValue) { // dayValue=“2014-01-01”
      const day = new Date(Date.parse(dayValue.replace(/-/g, '/'))); // 将日期值格式化
      const today = []; // 创建星期数组
      this.weeks.map((item) => {
        today.push(item.fullName);
      });
      return today[day.getDay()]; // 返一个星期中的某一天，其中0为星期日
    },
    /**
     * 获取俩个月月份排序。获取年份数据
     * mm 月份
     * yy 年份
     * operate 切换操作方式
     */
    orderMonthFunc(mm, yy, operate) {
      this.orderMonth = [];
      const nowMM = mm;
      // 俩个月的月份
      switch (operate) {
        case 'created': {
          if (nowMM == this.month[11]) {
            this.orderMonth.push(nowMM, this.month[0]);
          } else {
            this.orderMonth.push(nowMM, nowMM + 1);
          }
          break;
        }
        case 'next': {
          if (nowMM == this.month[11]) {
            this.orderMonth.push(this.month[0], this.month[1]);
          } else if (nowMM + 1 == this.month[11]) {
            this.orderMonth.push(nowMM + 1, this.month[0]);
          } else {
            this.orderMonth.push(nowMM + 1, nowMM + 2);
          }
          break;
        }
        case 'prev': {
          if (nowMM == this.month[0]) {
            this.orderMonth.push(this.month[11] - 2, this.month[11] - 1);
          } else if (nowMM - 2 == this.month[0]) {
            this.orderMonth.push(this.month[11], this.month[0]);
          } else if (nowMM - 1 == this.month[0]) {
            this.orderMonth.push(this.month[11] - 1, this.month[11]);
          } else {
            this.orderMonth.push(nowMM - 3, nowMM - 2);
          }
          break;
        }
        default: break;
      }

      // 俩个月的年份
      this.orderMonth.map((item) => {
        switch (operate) {
          case 'created':
          case 'next': {
            if (item >= nowMM) {
              this.aYear.push({ year: yy, month: item });
            } else {
              this.aYear.push({ year: yy + 1, month: item });
            }
            break;
          }
          case 'prev': {
            if (nowMM <= item) {
              this.aYear.push({ year: yy - 1, month: item });
            } else {
              this.aYear.push({ year: yy, month: item });
            }
            break;
          }
          default: break;
        }
      });
    },
    // 获取俩月的日历数据
    get_twoMonth_Data(selYY, selMM, operate) {
      this.aYearData = [];
      this.aYear = [];
      // 当前时间的俩月年份
      this.orderMonthFunc(selMM, selYY, operate);
      this.aYear.map((item) => {
        this.aYearData.push({
          title: `${item.year}年${item.month + 1}月`,
          aMonthData: this.get_amonth_list(item.year, item.month),
        });
      });
    },
    // 获取一个月的列表
    get_amonth_list($yy, $mm) {
      // 定义每个月的天数，如果是闰年第二月改为29天
      // year=2018;month=1(js--month=0~11)
      const daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
      if (($yy % 4 === 0 && $yy % 100 !== 0) || $yy % 400 === 0) {
        daysInMonth[1] = 29;
      }
      // 获得指定年月的1号是星期几
      const targetDay = new Date($yy, $mm, 1).getDay();
      // 将要在calendar__main中渲染的列表
      const calendarList = [];
      const preNum = targetDay;
      // 首先先说一下，我们的日期是(日--六)这个顺序也就是(0--6)
      // 有了上述的前提我们可以认为targetDay为多少，我们就只需要在calendarList的数组中push几个content为''的obj作为占位
      if (targetDay > 0) {
        for (let i = 0; i < preNum; i++) {
          const obj = {
            type: 'pre',
            content: '',
            yy: '',
            mm: '',
          };
          calendarList.push(obj);
        }
      }
      for (let i = 0; i < daysInMonth[$mm]; i++) {
        const obj = {
          type: 'normal',
          content: (i + 1) > 9 ? `${(i + 1)}` : `0${(i + 1)}`,
          yy: $yy,
          mm: ($mm + 1) > 9 ? `${($mm + 1)}` : `0${($mm + 1)}`,
        };
        calendarList.push(obj);
      }
      // 凑足6排日期的尾部
      const reduceLen = 42 - calendarList.length;
      for (let m = 0; m < reduceLen; m++) {
        const obj_end = {
          type: 'pre',
          content: '',
          yy: '',
          mm: '',
        };
        calendarList.push(obj_end);
      }

      // 将一个月的数据切割成以周为单位的
      const calendarListArr = [];
      let len = -1;
      calendarList.map((item, index) => {
        if (index % 7 == 0) {
          calendarListArr.push([]);
        }
      });
      calendarList.map((item, idx) => {
        if (idx % 7 == 0) {
          len++;
        }
        calendarListArr[len].push(item);
      });
      return calendarListArr;
    },
    // 点击一天，改变样式，获取选中值
    /**
     * @param {object} data 一天的数据
     * @param {number} idx 选中的天序号
     * @param {number} index 选中的年序号
     * @param {string} selYYMM 选中的年月值
     * @param {number} selDD 选中的天值
     */
    clkdayBoxFn(data, idx, index, selYYMM, selDD) {
      if (data.type !== 'pre') {
        const everSelDate = this.selDate;
        const selYY = selYYMM.substring(0, selYYMM.indexOf('年'));
        const selMM = selYYMM.substring(selYYMM.indexOf('年') + 1, selYYMM.indexOf('月'));
        this.selDate = `${selYY}-${selMM > 9 ? selMM : `0${selMM}`}-${selDD}`;
        // 过去的日期不可选
        if (Date.parse(this.selDate) - Date.parse(`${this.nowYY}-${this.nowMM + 1}-${this.nowDD}`) < 0) {
          this.selDate = everSelDate;
          return false;
        }
        this.$emit('close-calendar', this.selDate);
      }
    },
    /**
     * 获取下俩个月的日期数据
     * $yy 日历框右侧年份
     * $leftYY 日历框左侧年份
     * $mm 日历框左侧月份
     */
    nextTwoMonthDate($yy, $leftYY, $mm) {
      this.notPrev = '';
      this.get_twoMonth_Data($yy, this.orderMonth[1], 'next');
    },
    /**
     * 获取前俩个月的日期数据
     * $leftYY 日历框左侧年份
     * $yy 日历框右侧年份
     * $mm 日历框左侧月份
     */
    prevTwoMonthDate($leftYY, $yy, $mm) {
      if (this.notPrev == '') {
        this.get_twoMonth_Data($yy, this.orderMonth[1], 'prev');
      }
    },
    // 设置向前翻按钮的样式
    changePrevCls($yy, $mm) {
      if ($yy == this.nowYY && $mm * 1 == this.nowMM + 1) {
        this.notPrev = ' disabled';
      } else {
        this.notPrev = '';
      }
      return this.notPrev;
    },
    // 为月份面板的天设置样式class
    setDayClass(val) {
      const refDateTime = new Date(val).getTime();
      const nowDateTime = new Date(new Date().toLocaleDateString()).getTime();
      let dayCls = '';
      if (refDateTime - nowDateTime < 0) {
        dayCls = this.everCls;
      } else if (refDateTime - nowDateTime < 24 * 60 * 60 * 1000) {
        dayCls = this.todayCls;
      } else {
        dayCls = '';
      }
      if (refDateTime - new Date(this.selDate).getTime() == 0) {
        dayCls += this.activeCls;
      }
      return dayCls;
    },
  },
};
</script>

<style lang="less" scoped>
// element样式修改
.el-date-picker__header {
  margin-bottom: 0;
  overflow: hidden;
}
.el-picker-panel__content {
  margin-top: 0;
  .cp-tit {
    text-align: center;
  }
}
.el-date-picker {
  width: 650px;
  .el-picker-panel__content {
    float: left;
  }
  table {
    border: 1px solid #ddd;
  }
}
.el-picker-panel__icon-btn {
  margin-top: 0;
  font-size: 20px;
  border: 1px solid #888;
  color: #888;
  &:hover {
    border-color: #ff5b1e;
    color: #ff5b1e;
  }
  &.disabled,
  &.disabled:hover {
    border-color: #ddd;
    color: #ddd;
    cursor: not-allowed;
  }
}
// 补充样式
.calendar-box {
  position: absolute;
  left:0;
  top: 88px;
  z-index: 999;
  .el-date-picker {
    margin-top: 0;
  }
}
</style>
